#pragma once

#include <memory>
#include "rtda/frame.h"
#include "instructions/base/instructions.h"

namespace jvm {
namespace instructions {

// Duplicate the top operand stack value
class DUP : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

// Duplicate the top operand stack value and insert two values down
class DUP_X1 : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

// Duplicate the top operand stack value and insert two or three values down
class DUP_X2 : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

// Duplicate the top one or two operand stack values
class DUP2 : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

// Duplicate the top one or two operand stack values and insert two or three values down
class DUP2_X1 : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

// Duplicate the top one or two operand stack values and insert two, three, or four values down
class DUP2_X2 : public NoOperandsInstruction {
public:
    void execute(std::shared_ptr<rtda::Frame> frame) override;
};

} // namespace instructions
} // namespace jvm